<?php
namespace Resmodel;

use Core\Config;
use Core\Constant;
use Core\Exception\BusinessException;
use Core\Helper\CommonHelper;
use Core\Helper\HtmlPurifierHelper;
use Core\Session\AdminSessionHelper;

use Model\LanguageAwareInterface;
use Resmodel\Factory\ResTableGatewayFactory;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Expression;
use Zend\Db\Sql\Predicate\Like;
use Zend\Db\Sql\Predicate\Operator;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\TableIdentifier;
use Zend\InputFilter\InputFilter;

class DishTable extends ResAbstractTable implements LanguageAwareInterface
{
    private $_lang;

    /**
     * @param $id
     * @return Dish
     */
    public function getDish($id){
        return $this->getById($id);
    }

    /**
     * @param $name
     * @return Dish
     */
    public function getDishByName($name)
    {
        return $this->getByColumn('name', $name)->current();
    }

    /**
     * @return InputFilter
     */
    public function getInputFilter()
    {
        $filter = new InputFilter();


        return $filter;
    }

    public function search($isPaging, $offset, $rowPerPage, $orderArr = array('name'), $searchOption){

        $select = $this->getDbSqlSelect();
        $select->join(array('dl'=>'dish_lang'), 'dish.id = dl.dish_id',
            array('name'=>'name', 'description'=>'description'))
        ->join(array('dc1'=>'dish_category'), 'dc1.dish_id = dish.id', array())
            ->where(array('dc1.is_primary'=>1))
            ->join(array('c'=>'ml_category'), 'dc1.category_id = c.id', array())
            ->join(array('mcl'=>'ml_category_lang'), 'mcl.category_id = c.id', array('category_name'=>'name'))
            ->where(array('mcl.lang'=>$this->getLang()))
            ->where(array('dl.lang'=>$this->getLang()));

        if($searchOption['name']){
            $select->where(array('dl.name like "%'.$searchOption['name'].'%"'));
        }

        if($searchOption['categoryId'] && $searchOption['categoryId'] != Constant::$SELECT_ALL_VALUE){
            $select->join(array('dc'=>'dish_category'), 'dc.dish_id = dish.id', array())
                ->where(array('dc.category_id'=>$searchOption['categoryId']));
        }



        if($isPaging){
            $select->offset($offset)->limit($rowPerPage);
        }

        if($orderArr){
            $select->order($orderArr);
        }

        $select->join( array('ur'=> new TableIdentifier('user', 'cms')),
            'ur.id = dish.created_by',
            array("user_name"=>"username"),'left');

        \Logger::debug($select->getSqlString($this->tableGateway->adapter->getPlatform()));

        $allRow = $this->executeSelectForArray($select);
        $dbMaxOrder = $this->getMaxOrderNumber();
        foreach ($allRow as $anArticle) {
            $anArticle->downable = 1;
            $anArticle->upable = 1;
            if($anArticle->order_number == 1)
                $anArticle->downable = 0;

            if($anArticle->order_number == $dbMaxOrder)
                $anArticle->upable = 0;

            $anArticle->order_number = ($anArticle->order_number - $dbMaxOrder -1)*(-1);

        }

        $result['rows'] = $allRow;

        $total = $this->getCount($select);

        $result['total'] = $total;

        return $result;


    }

    public function getLang()
    {
        return $this->_lang;
    }

    public function setLang($lang)
    {
        $this->_lang = $lang;
    }


    public function addDish($paramArr){
        $dbMaxOrder = $this->getMaxOrderNumber();
        if(!$dbMaxOrder || $dbMaxOrder == 0)
            $dbMaxOrder = 1;
        else
            $dbMaxOrder++;

        $name = $paramArr['name'];
        $description = $paramArr['description'];
        $active = $paramArr['active'];

        $content = $paramArr['content'];
        $ingredient = $paramArr['ingredient'];
        $howTo = $paramArr['howTo'];
        $mainCategories = $paramArr['categories'];
        $subCategories = $paramArr['subcategories'];
        $priceArr = $paramArr['priceArr'];
        $properties = $paramArr['properties'];
        $allImages = $paramArr['allImages'];


        $propertiesAsString =  '';
        if( count($properties) > 0)
            $propertiesAsString = implode(Constant::$SYSTEM_DELIMINATOR, $properties);

        $dishId = $this->insert(array('property' => $propertiesAsString,
            'active'=>$active, 'order_number'=>$dbMaxOrder));

        $dishLangTable = ResTableGatewayFactory::getDishLangTable();
        $dishLangTable->insert(array('dish_id'=>$dishId, 'content'=>$content,
            'alias'=>CommonHelper::vietnameseToASCII($name),
            'how_to'=>$howTo, 'ingredient'=>$ingredient, 'name'=>$name,
            'description'=>$description));

        $allLangCodes = Config::getLangCodes();
        foreach ($allLangCodes as $aLang) {
            if($aLang != $this->getLang())
                $dishLangTable->insert(array('lang'=>$aLang, 'dish_id'=>$dishId,
                    'name'=>Constant::$DEFAULT_LANG_NEED_UPDATE,
                'content'=>Constant::$DEFAULT_LANG_NEED_UPDATE,
                    'how_to'=>Constant::$DEFAULT_LANG_NEED_UPDATE,
                    'ingredient'=>Constant::$DEFAULT_LANG_NEED_UPDATE,
                    'description'=>Constant::$DEFAULT_LANG_NEED_UPDATE,));
        }


        $dishCategoryTable = ResTableGatewayFactory::getDishCategoryTable();
        if($mainCategories)
            $dishCategoryTable->insert(array('dish_id'=>$dishId,
                'category_id'=>$mainCategories, 'is_primary'=>1));

        if($subCategories)
            foreach ($subCategories as $aCategory) {
                if($aCategory != $mainCategories)
                $dishCategoryTable->insert(array('dish_id'=>$dishId,
                        'category_id'=>$aCategory, 'is_primary'=>0));
            }

//        $dishTagTable = ResTableGatewayFactory::getDishTagTable($this->getLang());
      /*  if($allTag)
            foreach ($allTag as $aTag) {
                $dishTagTable->insert(array('dish_id'=>$dishId, 'tag'=>$aTag));
            }*/

//        throw new BusinessException('mama calls me');

        $dishPriceTable = ResTableGatewayFactory::getDishPriceTable();
        $unitTable = ResTableGatewayFactory::getUnitTable($this->getLang());
        if($priceArr)
            foreach ($priceArr as $aPrice) {
                $unitItem = $unitTable->getUnitByName($aPrice['unit']);
                $unitIdStr = $unitItem?$unitItem->id:null;
                $dishPriceTable->insert(array('dish_id'=>$dishId, 'price'=>str_replace(array('.', ',') , '', $aPrice['price']),
                    'currency_unit'=>$aPrice['currency_unit'], 'unit_id'=>$unitIdStr));
            }

//        $dishArticleTable = ResTableGatewayFactory::getDishArticleTable($this->getLang());
        /*if($articleArr)
            foreach ($articleArr as $anArticle) {
                $dishArticleTable->insert(array('lang'=>$dishArticleTable->getLang(),
                    'title'=>$anArticle['title'],'url'=>$anArticle['url'], 'dish_id'=>$dishId));
            }*/

        $dishImageTable = ResTableGatewayFactory::getDishImageTable();
        if($allImages)
            foreach ($allImages as $anImage) {
                $description = HtmlPurifierHelper::purifyDefault($anImage['description']);
                $dishImageTable->insert(array('dish_id'=>$dishId,
                    'path'=>$anImage['path'], 'description'=>$description));
            }

    }

    public function updateDish($paramArr, $id){

        $name = $paramArr['name'];
        $description = $paramArr['description'];
        $active = $paramArr['active'];
//        $allTag = $paramArr['allTag'];
        $content = $paramArr['content'];
        $ingredient = $paramArr['ingredient'];
        $howTo = $paramArr['howTo'];
        $mainCategories = $paramArr['categories'];
        $subCategories = $paramArr['subcategories'];
        $priceArr = $paramArr['priceArr'];
        $properties = $paramArr['properties'];
//        $articleArr = $paramArr['articleArr'];
        $allImages = $paramArr['allImages'];


        if(strlen($name) == 0)
            throw new BusinessException('Chưa nhập tên');
        if(strlen($description) == 0)
            throw new BusinessException('Chưa nhập mô tả');

        $propertiesAsString =  '';
        if( count($properties) > 0)
            $propertiesAsString = implode(Constant::$SYSTEM_DELIMINATOR, $properties);

        $this->update(array('property' => $propertiesAsString, 'active'=>$active), $id);

        $dishItem = $this->getDish($id);
        $dishLangItem = $dishItem->getDishLang($this->getLang());
        $dishLangTable = ResTableGatewayFactory::getDishLangTable($this->getLang());
        $dishLangTable->update(array('dish_id'=>$id, 'content'=>$content,
            'how_to'=>$howTo, 'ingredient'=>$ingredient, 'name'=>$name,
            'alias'=>CommonHelper::vietnameseToASCII($name),
            'description'=>$description), $dishLangItem->id);

        $dishItem->detachCategories();

        $dishCategoryTable = ResTableGatewayFactory::getDishCategoryTable();
        if($mainCategories)
            $dishCategoryTable->insert(array('dish_id'=>$id,
                'category_id'=>$mainCategories, 'is_primary'=>1));

        if($subCategories)
            foreach ($subCategories as $aCategory) {
                if($aCategory != $mainCategories)
                $dishCategoryTable->insert(array('dish_id'=>$id,
                    'category_id'=>$aCategory, 'is_primary'=>0));
            }


//        $dishItem->detachTags($this->getLang());
        /*$dishTagTable = ResTableGatewayFactory::getDishTagTable($this->getLang());
        if($allTag)
            foreach ($allTag as $aTag) {
                $dishTagTable->insert(array('dish_id'=>$id, 'tag'=>$aTag));
            }*/

//        throw new BusinessException('mama calls me');
        $dishItem->detachPrices();
        $dishPriceTable = ResTableGatewayFactory::getDishPriceTable();
        $unitTable = ResTableGatewayFactory::getUnitTable($this->getLang());
        if($priceArr)
            foreach ($priceArr as $aPrice) {
                $unitItem = $unitTable->getUnitByName($aPrice['unit']);
                $unitIdStr = $unitItem?$unitItem->id:null;
                $dishPriceTable->insert(array('dish_id'=>$id, 'price'=>str_replace(array('.', ','), '', $aPrice['price']),
                    'currency_unit'=>$aPrice['currency_unit'], 'unit_id'=>$unitIdStr));
            }

//        $dishItem->detachArticles($this->getLang());
        /*$dishArticleTable = ResTableGatewayFactory::getDishArticleTable($this->getLang());
        if($articleArr)
            foreach ($articleArr as $anArticle) {
                $dishArticleTable->insert(array('lang'=>$dishArticleTable->getLang(),
                    'title'=>$anArticle['title'],'url'=>$anArticle['url'], 'dish_id'=>$id));
            }*/

        $dishItem->detachImages();
        $dishImageTable = ResTableGatewayFactory::getDishImageTable();
        if($allImages)
            foreach ($allImages as $anImage) {
                $dishImageTable->insert(array('dish_id'=>$id,
                    'path'=>$anImage['path'], 'description'=>$anImage['description']));
            }
    }

    public function toggleActive($id){
        $dish = $this->getDish($id);
        $active = $dish->active == 1?0:1;
        $this->update(array('active'=>$active), $id);
    }

    public function doDelete($id){
        $dish = $this->getDish($id);
        $dish->detachCategories();
        $this->delete($id);

        $dishLangTable = ResTableGatewayFactory::getDishLangTable();
        $dishLangTable->getTableGateway()->delete(array('dish_id'=>$id));

        $dishImageTable = ResTableGatewayFactory::getDishImageTable();
        $dishImageTable->getTableGateway()->delete(array('dish_id'=>$id));

        $dishPriceTable = ResTableGatewayFactory::getDishPriceTable();
        $dishPriceTable->getTableGateway()->delete(array('dish_id'=>$id));

        $dishTagTable = ResTableGatewayFactory::getDishTagTable();
        $dishTagTable->getTableGateway()->delete(array('dish_id'=>$id));

        //rearrange order_number

        $this->getTableGateway()->update(array('order_number'=>new Expression('order_number - 1')),
            array('order_number > '.$dish->order_number));

    }

    public function upDish($id){
        $dish = $this->getDish($id);
        $brother = $this->getUpperBrother($dish);
        $this->update(array('order_number'=>$brother->order_number - 1),$brother->id );
        $this->update(array('order_number'=>$dish->order_number + 1),$dish->id );
    }

    private function getUpperBrother($sample){
        $brotherOrder = $sample->order_number + 1;
        $brother = $this->getByColumn('order_number', $brotherOrder)->current();
        if(!$brother) throw new BusinessException('Không tìm được món ăn xếp trên');
        return $brother;
    }
    private function getLowerBrother($sampleArticle){
        $brotherOrder = $sampleArticle->order_number - 1;
        $brother = $this->getByColumn('order_number', $brotherOrder)->current();
        if(!$brother) throw new BusinessException('Không tìm được món ăn xếp trên');
        return $brother;
    }

    public function downDish($id){
        $dish = $this->getDish($id);
        $brother = $this->getLowerBrother($dish);
        $this->update(array('order_number'=>$brother->order_number + 1),$brother->id );
        $this->update(array('order_number'=>$dish->order_number - 1),$dish->id );
    }

    public function getAllDishOfCategory($categoryId ,$isPrimary = -1){
        $select = $this->getDbSqlSelect();
        $select->join(array('dc'=>'dish_category'), 'dc.dish_id = dish.id', array())
        ->join(array('dl'=>'dish_lang'), 'dl.dish_id = dish.id', array('name'=>'name'))
        ->where(array('dl.lang'=>$this->getLang()))
            ->where(array('dc.category_id'=>$categoryId))
        ->order('dish.order_number desc');
        if($isPrimary > -1)
            $select->where(array('dc.is_primary'=>$isPrimary));
        return  $this->executeSelectForArray($select);
    }

}